home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / MPW_TOOL / TOOLS / TOOLS_WI / ICON_8 / ICONX_FO / OCAT.C < prev    next >
Text File  |  1990-03-02  |  3KB  |  126 lines

  1. /*
  2.  * File: ocat.c
  3.  *  Contents: cat, lconcat
  4.  */
  5.  
  6. #include "::h:config.h"
  7. #include "::h:rt.h"
  8. #include "rproto.h"
  9.  
  10. #ifdef PreProcess
  11. /* include(../M4/ops.m4) /* */
  12. /* */
  13. #endif                    /* PreProcess */
  14.  
  15. /*
  16.  * x || y - concatenate strings x and y.
  17.  */
  18.  
  19. OpDcl(cater,2,"||")
  20.    {
  21.    char sbuf1[MaxCvtLen];    /* buffers for conversion to string */
  22.    char sbuf2[MaxCvtLen];
  23.  
  24.    /*
  25.     *  Convert arguments to strings if necessary.
  26.     */
  27.    if (cvstr(&Arg1, sbuf1) == CvtFail) 
  28.       RunErr(103, &Arg1);
  29.    if (cvstr(&Arg2, sbuf2) == CvtFail) 
  30.       RunErr(103, &Arg2);
  31.  
  32.    if (StrLoc(Arg1) + StrLen(Arg1) == strfree) {
  33.       /*
  34.        * The end of Arg1 is at the end of the string space.  Hence,
  35.        *  Arg1 was the last string allocated.  Arg1 is not copied.
  36.        *  Instead, Arg2 is appended to the string space and the
  37.        *  result is pointed to the start of Arg1.
  38.        *  Space is only needed for the string being appended
  39.        */
  40.       if (strreq(StrLen(Arg2)) == Error) 
  41.      RunErr(0, NULL);
  42.       StrLoc(Arg0) = StrLoc(Arg1);
  43.       }
  44.    else {
  45.       /*
  46.        * Ensure space for the resulting concatenated string
  47.        */
  48.       if (strreq(StrLen(Arg1) + StrLen(Arg2)) == Error) 
  49.      RunErr(0, NULL);
  50.       /*
  51.        * Otherwise, append Arg1 to the end of the string space and
  52.        *  point the result to the start of Arg1.
  53.        */
  54.       StrLoc(Arg0) = alcstr(StrLoc(Arg1),StrLen(Arg1));
  55.       }
  56.  
  57.    /*
  58.     * Append Arg2 to the end of the string space.
  59.     */
  60.    alcstr(StrLoc(Arg2),StrLen(Arg2));
  61.    /*
  62.     *  Set the length of the result and return.
  63.     */
  64.    StrLen(Arg0) = StrLen(Arg1) + StrLen(Arg2);
  65.    Return;
  66.    }
  67.  
  68. /*
  69.  * x ||| y - concatenate lists x and y.
  70.  */
  71.  
  72. OpDcl(lconcat,2,"|||")
  73.    {
  74.    register struct b_list *bp1, *bp2;
  75.    register struct b_lelem *lp1, *lp2;
  76.    word size1, size2;
  77.  
  78.    /*
  79.     * x and y must be lists.
  80.     */
  81.    if (Arg1.dword != D_List) 
  82.       RunErr(108, &Arg1);
  83.    if (Arg2.dword != D_List) 
  84.       RunErr(108, &Arg2);
  85.  
  86.    /*
  87.     * Get the size of both lists.
  88.     */
  89.    size1 = BlkLoc(Arg1)->list.size;
  90.    size2 = BlkLoc(Arg2)->list.size;
  91.  
  92.    /*
  93.     * Make a copy of both lists.
  94.     */
  95.    if (cplist(&Arg1, &Arg1, (word)1, size1 + 1) == Error) 
  96.       RunErr(0, NULL);
  97.    if (cplist(&Arg2, &Arg2, (word)1, size2 + 1) == Error) 
  98.       RunErr(0, NULL);
  99.  
  100.    /*
  101.     * Get a pointer to both lists.  bp1 points to the copy of Arg1 and is
  102.     *  the list that will be returned.
  103.     */
  104.    bp1 = (struct b_list *) BlkLoc(Arg1);
  105.    bp2 = (struct b_list *) BlkLoc(Arg2);
  106.  
  107.    /*
  108.     * Perform the concatenation by hooking the lists together.
  109.     */
  110.    lp1 = (struct b_lelem *) bp1->listtail;
  111.    lp2 = (struct b_lelem *) bp2->listhead;
  112.  
  113.    lp1->listnext = (union block *) lp2;
  114.  
  115.    lp2->listprev = (union block *) lp1;
  116.  
  117.    /*
  118.     * Adjust the size field to reflect the length of the concatenated lists.
  119.     */
  120.    bp1->size = size1 + size2;
  121.    bp1->listtail = bp2->listtail;
  122.  
  123.    Arg0 = Arg1;
  124.    Return;
  125.    }
  126.